package com.globagames.isometric.core.view
{
	import com.globagames.isometric.core.event.IsoMapMouseEvent;
	import com.globagames.isometric.core.event.IsoObjectMouseEvent;
	import com.globagames.isometric.core.event.OperationEvent;
	import com.globagames.isometric.core.model.Block;
	import com.globagames.isometric.core.model.IIsoObject;
	import com.globagames.isometric.core.model.IMapModule;
	import com.globagames.isometric.core.model.IsoEngineModelLocator;
	import com.globagames.isometric.core.model.IsoTile;
	import com.globagames.isometric.core.model.SimpleObject;
	import com.globagames.isometric.core.util.CollisionManager;
	
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BitmapDataChannel;
	import flash.display.Shape;
	import flash.events.MouseEvent;
	import flash.filters.BitmapFilter;
	import flash.filters.BitmapFilterQuality;
	import flash.filters.BlurFilter;
	import flash.filters.ColorMatrixFilter;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.Timer;
	
	import mx.controls.Image;
	import mx.core.BitmapAsset;
	import mx.core.UIComponent;
	import mx.events.DragEvent;
	import mx.managers.DragManager;
	import mx.messaging.Producer;
	import mx.messaging.messages.AsyncMessage;
	
	import org.cove.ape.APEngine;
	import org.cove.ape.AbstractParticle;
	import org.cove.ape.CollisionEvent;
	import org.cove.ape.Group;
	import org.cove.ape.RectangleParticle;
	import org.cove.ape.Vector;
	
	[Event(name="tileClicked", type="com.globagames.isometric.core.event.IsoMapMouseEvent")]
	
	[Event(name="mouseOverObject", type="com.globagames.isometric.core.event.IsoObjectMouseEvent")]
	[Event(name="mouseOutObject", type="com.globagames.isometric.core.event.IsoObjectMouseEvent")]
	[Event(name="mouseClickObject", type="com.globagames.isometric.core.event.IsoObjectMouseEvent")]
	
	[Event(name="PlaceIsoObject", type="com.globagames.isometric.core.event.OperationEvent")]
	[Event(name="MoveIsoMap", type="com.globagames.isometric.core.event.OperationEvent")]
	public class IsoMap extends UIComponent
	{
		[Embed(source="assets/mask-visibility.png")]
        [Bindable]
        private var imgVisibilityCls:Class;
            
		private var model:IsoEngineModelLocator = IsoEngineModelLocator.getInstance();
		public var myTimer:Timer;
		private var testDisplay:Boolean = false;
		// DISPLAY
		private var visx:int;
		private var visy:int;
		private var onScreen:BitmapData ;
		private var offScreen:BitmapData;
		private var offScreenVisibility:BitmapData;
		
		public var ground:Image;
		public var canevas:Shape;
		private var zeroPoint:Point = new Point(0, 0);
		public var visibleRect:Rectangle;
		
		private var leftRect:Rectangle;
		private var rigthRect:Rectangle;
		private var upRect:Rectangle;
		private var downRect:Rectangle;
		
		private var tileSize:int;
		private var tileSizeHalf:int;
		private var tileSizeDouble:int;
		// DISPLAYED SCREEN STATES
		public var displayX3d:int = 0;
		public var displayY3d:int = 0;
		public var upleftXi:int = 0;
		public var upleftYi:int = 0;
		
		
		// MOUSE POINTER
		public var regX:Number;
		public var regY:Number;
		public var regNewX:Number;
		public var regNewY:Number;		
		public var draggable:Boolean = true;
		public var hasClicked:Boolean = false;
		
		// RETRACE STATES
		public var doRetrace:Boolean = false;
		public var doRetraceIsotile:Boolean = false;

		private  var _mapModule:IMapModule;
		
		public var mouseOverObject:Boolean = false;
		public var currentIsoObjectMouseOver:IIsoObject;
		public var currentIsoObjectPoint3d:Point;
		public var current2DPosition:Point;

		public var operations:Array = new Array();
		public var newOperations:Array = new Array();
		public var isoObjects:Object = new Object();
		public var isoObjectsArray:Array = new Array();
		private var _segments:Array = new Array(); 
		private var p:Point = new Point(0,0);
		
		public var apeContainer:UIComponent;
		public var apeDefaultGroup:Group = new Group();

		
		
		public var isInitialized : Boolean = false;
		
		
		public var zoneClipIsoTile:Rectangle;
		public var isotile:IsoTile;
		
		public function IsoMap()
		{
			super();		
		}
		override protected function createChildren():void{
			super.createChildren();
	
		}
		private function initializeDisplay():void {
			tileSize = _mapModule.tileSize;
			tileSizeHalf = _mapModule.tileSize/2;
			tileSizeDouble = _mapModule.tileSize * 2;
			this.width = _mapModule.mapWidth;
			this.height = _mapModule.mapHeight;
			if(ground) this.removeChild(ground);
			visx = (width / tileSizeDouble) + 2 ;
			visy = (height / tileSize) + 2;
			onScreen = new BitmapData(width, height ,false,0xffffff00);
			offScreen = new BitmapData(onScreen.width + _mapModule.tileSize*4 , onScreen.height +_mapModule.tileSize*2,false,0xffffff00);
			offScreenVisibility = new BitmapData(onScreen.width + _mapModule.tileSize*4 , onScreen.height +_mapModule.tileSize*2,false,0xffffff00);
			var clip:Bitmap = new Bitmap(onScreen);
			ground = new Image();			
			ground.width = onScreen.width;
			ground.height = onScreen.height;
			ground.source = clip; 
			visibleRect = new Rectangle(tileSize*2,tileSize, width, height);
			var startingPostion:IsoTile = _mapModule.tilesTable[_mapModule.startingY][_mapModule.startingX] as IsoTile;
			this.displayX3d = startingPostion.x3d;
			this.displayY3d = startingPostion.y3d;
			this.upleftXi = _mapModule.startingX;
			this.upleftYi = _mapModule.startingY;
			onScreen.copyPixels(offScreen,visibleRect, zeroPoint );			
			apeContainer = new UIComponent();
			apeContainer.x = 0;
			apeContainer.y = 0;
			apeContainer.visible = false;
			APEngine.init(1/4);
	        APEngine.container = apeContainer;
	        APEngine.addMasslessForce(new Vector(0,0));
	        APEngine.constraintCollisionCycles = 4; 
	        apeDefaultGroup.collideInternal = true;
	        APEngine.addGroup(apeDefaultGroup);
			this.addChildAt(ground,0);	
			canevas = new Shape();
			canevas.alpha = 0.2;
			this.addChildAt(canevas,1);
			this.addChild(apeContainer);
	        APEngine.step();
			systemManager.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
			doRetrace = true;
		}
		
		
		private function mouseMoveHandler(event:MouseEvent):void {			
			invalidateDisplayList();			
		}
		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {			
			super.updateDisplayList(unscaledWidth, unscaledHeight);
			if( _mapModule) {
				onScreen.copyPixels(offScreen,visibleRect, zeroPoint );	
				if( !model.draggingMapIsOn ) {	
					var ba:BitmapAsset = new imgVisibilityCls() as BitmapAsset;
					var r:Rectangle = new Rectangle(mouseX-128 + visibleRect.x, mouseY-128 +visibleRect.y, 256,256);				
					ba.bitmapData.copyChannel(offScreenVisibility,r, zeroPoint,BitmapDataChannel.BLUE, BitmapDataChannel.BLUE);
					ba.bitmapData.copyChannel(offScreenVisibility,r, zeroPoint,BitmapDataChannel.RED, BitmapDataChannel.RED);
					ba.bitmapData.copyChannel(offScreenVisibility,r, zeroPoint,BitmapDataChannel.GREEN, BitmapDataChannel.GREEN);
					onScreen.copyPixels(ba.bitmapData, ba.bitmapData.rect, new Point(mouseX-128,mouseY-128));
				}
			}
			if( newOperations.length>0){			
				while(newOperations.length>0) {
					var op:String = newOperations.shift();
					operations.push(op);					
				}										
				invalidateProperties();
			}
		}
		
		public function set mapModule(m:IMapModule) :void {
			isInitialized = false;
			_mapModule = m;
			initializeDisplay();
			isInitialized = true;						
		}
		
		public function get mapModule() : IMapModule {
			return _mapModule;
		}
		
		
		
		public function removeAllAPE(ar:Array):void {
			if( ar ) {
				for (var i:int = 0 ; i < ar.length ; i++ ) {
					var p:AbstractParticle = ar[i] as AbstractParticle;
					apeDefaultGroup.removeParticle(p);				
				}
				ar.splice(0,ar.length);
			}
		}
		
		public function populateAroundAPE(isotile:IsoTile):Array {
			var mxi:int = isotile.x2d - 3;
			var myi:int = isotile.y2d - 3;
			var ar:Array = new Array();
			var r:RectangleParticle = new RectangleParticle((mxi-2)*32,(yi+3)*32,32*6,32*18,0,true);
			
			
			for (var yi:int = myi ; yi < myi + 7 ; yi++ ) {
				for (var xi:int = mxi ; xi < mxi + 7 ; xi++ ) {
					var isoTile:IsoTile = mapModule.tilesTable[yi][xi] as IsoTile;
					if( isoTile && isoTile.design.length > 1 ) {
						var r:RectangleParticle = new RectangleParticle(isoTile.x2d*32+tileSizeHalf,isoTile.y2d*32+tileSizeHalf,32,32,0,true);							
						apeDefaultGroup.addParticle(r);
						ar.push(r);
					}
				}
			}
			return ar;
		}
		public function populateAPE():void {
			var lvisx:int = visx+2;			
			var mxi:int = upleftXi - 3;
			var myi:int = upleftYi + 2;
			var test:Boolean;			
			for (var yi:int = 0 ; yi <= visy*2 +20 ; yi++ ) {	
				test = ( yi%2 == 0 );				
				for (var xi:int = 0 ; xi < lvisx ; xi++ ) {	
					var xtile:int = mxi + xi;
					var ytile:int = myi - xi;
					var isoTile:IsoTile = mapModule.tilesTable[ytile][xtile] as IsoTile;
					if( isoTile && isoTile.design.length > 1 ) {
						var r:RectangleParticle = new RectangleParticle(isoTile.x2d*32+tileSizeHalf,isoTile.y2d*32+tileSizeHalf,32,32,0,true);							
						apeDefaultGroup.addParticle(r);												
					}						
				}
				if( !test) {					
					myi++;
				} else {					
					mxi++;
				}				
			}							
		}
		
		
		
		private function retraceIsotile(blockType:int):void {
			var mxi:int = isotile.x2d -16-2;
			var myi:int = isotile.y2d -11+2;		
			zoneClipIsoTile = new Rectangle(isotile.x3d -displayX3d -tileSize*4, isotile.y3d - displayY3d - tileSize * 12 +tileSizeHalf, 5*tileSizeDouble,13*tileSize + tileSizeHalf);
			var zone :int = 4 ;  
			var test:Boolean;
			for (var yi:int = 0 ; yi <= 50 ; yi++ ) {	
				test = ( yi%2 == 0 );
				if( test) {
					display(blockType,mxi,myi,zone );
					display(blockType,mxi+1,myi-1,zone );
					display(blockType,mxi+2,myi-2,zone );	
					display(blockType,mxi+3,myi-3,zone );
					display(blockType,mxi+4,myi-4,zone );
					display(blockType,mxi+5,myi-5,zone );
					display(blockType,mxi+6,myi-6,zone );
					display(blockType,mxi+7,myi-7,zone );
					mxi++;
				} else {
					display(blockType,mxi,myi,zone );
					display(blockType,mxi+1,myi-1,zone );	
					display(blockType,mxi+2,myi-2,zone );
					display(blockType,mxi+3,myi-3,zone );
					display(blockType,mxi+4,myi-4,zone );
					display(blockType,mxi+5,myi-5,zone );
					display(blockType,mxi+6,myi-6,zone );									
					myi++;
				}				
			}
		}
		private function retrace(blockType:int, zone:int = -1):void {						
			var lvisx:int = visx+2;			
			var mxi:int = upleftXi - 3;
			var myi:int = upleftYi + 2;
			// upper zone, first line				
			display(blockType, mxi,myi,zone);
			for (var xi:int = 1 ; xi < lvisx ; xi++ ) {	
				display(blockType, (mxi + xi) ,(myi - xi)  ,zone);
			}
			display(blockType,(mxi + lvisx ),(myi - lvisx),zone);
			mxi++;			
			// upper zone, second line (no clip to do)						
			for (var xi:int = 0 ; xi < lvisx ; xi++ ) {	
				display(blockType,(mxi + xi) ,(myi - xi) ,zone);
			}
			myi++;			
			// upper zone, third line	
			display(blockType,mxi,myi,zone);
			for (var xi:int = 1 ; xi < lvisx ; xi++ ) {	
				display(blockType,(mxi + xi) ,(myi - xi)  ,zone);
			}			
			display(blockType,mxi + lvisx,myi - lvisx  ,zone);
			mxi++;			
			// center zone					
			var test:Boolean;
			for (var yi:int = 3 ; yi <= visy*2 +20 ; yi++ ) {	
				test = ( yi%2 == 0 );
				if( !test) {
					for (var xi:int = 0 ; xi < lvisx ; xi++ ) {	
						display(blockType,mxi + xi ,myi - xi ,zone );
					}
					myi++;
				} else {
					display(blockType,mxi,myi,zone);
					for (var xi:int = 1 ; xi < lvisx ; xi++ ) {	
						display(blockType,mxi + xi ,myi - xi  ,zone);
					}
					display(blockType,mxi + lvisx,myi - lvisx , zone );
					mxi++;
				}				
			}			
			doRetrace = false;			
		}
		private function retraceUp(blockType:int):void {
			if ( blockType == Block.TYPE_SOL ) {
				offScreen.scroll(0,tileSize);				
			}
			var lvisx:int = visx+2;
			var mxi:int = upleftXi - 3-1;
			var myi:int = upleftYi + 2-1;
			// upper zone, first line
			display(blockType,mxi,myi,  0 );
			for (var xi:int = 1 ; xi < lvisx ; xi++ ) {	
				display(blockType, (mxi + xi) ,(myi - xi) ,  0 );
			}
			display(blockType,(mxi + lvisx ),(myi - lvisx),  0  );
			mxi++;			
			// upper zone, second line (no clip to do)	
			for (var xi:int = 0 ; xi < lvisx ; xi++ ) {	
				display(blockType,(mxi + xi) ,(myi - xi) ,  0  );
			}
			myi++;			
			// upper zone, third line				
			display(blockType,mxi,myi, 0 );			
			for (var xi:int = 1 ; xi < lvisx ; xi++ ) {	
				display(blockType,(mxi + xi) ,(myi - xi) ,  0  );
			}			
			display(blockType,mxi + lvisx,myi - lvisx,  0  );
			mxi++;	
			// center zone		
			var test:Boolean;
			for (var yi:int = 3 ; yi <= 28 ; yi++ ) {	
				test = ( yi%2 == 0 );
				if( !test) {
					for (var xi:int = 0 ; xi < lvisx ; xi++ ) {	
						display(blockType,mxi + xi ,myi - xi ,  0);
					}
					myi++;
				} else {
					display(blockType,mxi,myi, 0);
					for (var xi:int = 1 ; xi < lvisx ; xi++ ) {	
						display(blockType,mxi + xi ,myi - xi ,  0);
					}
					display(blockType,mxi + lvisx,myi - lvisx,  0);
					mxi++;
				}				
			}					
		}
		private function retraceDown(blockType:int):void {
			//trace("retraceDown");
			if ( blockType == Block.TYPE_SOL ) {
				offScreen.scroll(0,-tileSize);			
			}			
			var lvisx:int = visx+2;
			var mxi:int = upleftXi - 3+(visy-1)-1;
			var myi:int = upleftYi + 2+(visy-1)-1;			
			// lower zone, first line
			display(blockType,mxi,myi, 2);
			for (var xi:int = 1 ; xi < lvisx ; xi++ ) {	
				display(blockType, (mxi + xi) ,(myi - xi) , 2 );
			}
			display(blockType,(mxi + lvisx ),(myi - lvisx), 2 );
			mxi++;
			// lower zone, second line (no clip to do)		
			for (var xi:int = 0 ; xi < lvisx ; xi++ ) {	
				display(blockType,(mxi + xi) ,(myi - xi) ,2 );
			}
			myi++;	
			// lower zone, third line	
			display(blockType,mxi,myi, 2);
			for (var xi:int = 1 ; xi < lvisx ; xi++ ) {	
				display(blockType,(mxi + xi) ,(myi - xi) , 2 );
			}
			display(blockType,mxi + lvisx,myi - lvisx, 2 );
			mxi++;	
			// down screen zone					
			var test:Boolean;
			for (var yi:int = visy*2 ; yi <= visy*2+20 ; yi++ ) {	
				test = ( yi%2 == 0 );
				if( !test) {
					for (var xi:int = 0 ; xi < lvisx ; xi++ ) {	
						display(blockType,mxi + xi ,myi - xi ,2 );
					}
					myi++;
				} else {
					display(blockType,mxi,myi, 2);
					for (var xi:int = 1 ; xi < lvisx ; xi++ ) {	
						display(blockType,mxi + xi ,myi - xi , 2 );
					}
					display(blockType,mxi + lvisx,myi - lvisx, 2 );
					mxi++;
				}				
			}
			
		}
		private function retraceLeft(blockType:int):void {
			if ( blockType == Block.TYPE_SOL ) {
				offScreen.scroll(tileSizeDouble,0);			
			}
			var zone:int = 3;
			var lvisx:int = 4;			
			var mxi:int = upleftXi - 3;
			var myi:int = upleftYi + 2;
			// upper zone, first line
			display(blockType, mxi,myi,zone);
			for (var xi:int = 1 ; xi < lvisx ; xi++ ) {	
				display(blockType, (mxi + xi) ,(myi - xi)  ,zone);
			}
			display(blockType,(mxi + lvisx ),(myi - lvisx),zone);
			mxi++;			
			// upper zone, second line (no clip to do)	
			for (var xi:int = 0 ; xi < lvisx ; xi++ ) {	
				display(blockType,(mxi + xi) ,(myi - xi) ,zone);
			}
			myi++;			
			// upper zone, third line	
			display(blockType,mxi,myi,zone);
			
			for (var xi:int = 1 ; xi < lvisx ; xi++ ) {	
				display(blockType,(mxi + xi) ,(myi - xi)  ,zone);
			}			
			display(blockType,mxi + lvisx,myi - lvisx  ,zone);
			mxi++;			
			// center zone		
			var test:Boolean;
			for (var yi:int = 3 ; yi <= visy*2+20 ; yi++ ) {	
				test = ( yi%2 == 0 );
				if( !test) {
					for (var xi:int = 0 ; xi < lvisx ; xi++ ) {	
						display(blockType,mxi + xi ,myi - xi ,zone );
					}
					myi++;
				} else {
					display(blockType,mxi,myi,zone);
					for (var xi:int = 1 ; xi < lvisx ; xi++ ) {	
						display(blockType,mxi + xi ,myi - xi  ,zone);
					}
					display(blockType,mxi + lvisx,myi - lvisx , zone );
					mxi++;
				}				
			}								
		}
		private function retraceRight(blockType:int):void {
			if ( blockType == Block.TYPE_SOL ) {
				offScreen.scroll(-tileSizeDouble,0);			
			}
			var lvisx:int = visx+2;
			var zone:int = 1;
			var mxi:int = upleftXi - 3;
			var myi:int = upleftYi + 2;
			// upper zone, first line
			for (var xi:int = lvisx-4 ; xi < lvisx ; xi++ ) {	
				display(blockType, (mxi + xi) ,(myi - xi)  ,zone);
			}
			display(blockType,(mxi + lvisx ),(myi - lvisx),zone);
			mxi++;			
			// upper zone, second line (no clip to do)	
			for (var xi:int = lvisx-4 ; xi < lvisx ; xi++ ) {	
				display(blockType,(mxi + xi) ,(myi - xi) ,zone);
			}
			myi++;			
			// upper zone, third line	
			for (var xi:int = lvisx-5 ; xi < lvisx ; xi++ ) {	
				display(blockType,(mxi + xi) ,(myi - xi)  ,zone);
			}			
			display(blockType,mxi + lvisx,myi - lvisx  ,zone);
			mxi++;			
			// center zone		
			var test:Boolean;
			for (var yi:int = 3 ; yi <= visy*2 + 20 ; yi++ ) {	
				test = ( yi%2 == 0 );
				if( !test) {
					for (var xi:int = lvisx-5 ; xi < lvisx ; xi++ ) {	
						display(blockType,mxi + xi ,myi - xi ,zone );
					}
					myi++;
				} else {
					display(blockType,mxi,myi,zone);
					for (var xi:int = lvisx-4 ; xi < lvisx ; xi++ ) {	
						display(blockType,mxi + xi ,myi - xi  ,zone);
					}
					display(blockType,mxi + lvisx,myi - lvisx , zone );
					mxi++;
				}				
			}						
		}
		
		
		private function display(blockType,xtile:int,ytile:int,  zone:int = -1):void {
			var cPoint:Point;
			var x3d:int;
			var y3d:int;
			var block:Block ;			
			// if outside of the map, display an empty tile, and only if dosplaying the ground
			if( ! (xtile >=0 && ytile >=0 && xtile < _mapModule.sizeX&& ytile < _mapModule.sizeY) ) {
				if ( blockType == Block.TYPE_SOL) {
					x3d = xtile*_mapModule.tileSize - ytile*_mapModule.tileSize;
					y3d = ( xtile*_mapModule.tileSize + ytile*_mapModule.tileSize )/2; 
					cPoint = new Point(x3d - displayX3d, y3d - displayY3d);
					var bd:BitmapData = _mapModule.bitmaps[ 0 ] as BitmapData;	
					var rect:Rectangle = (_mapModule.bitmapsRects[0] as Block).rect;	
					copyPixelsCliped(bd, rect, cPoint, zone);
				}
			// else display the tile
			} else {
				var isoTile:IsoTile = mapModule.tilesTable[ytile][xtile] as IsoTile;			 
				cPoint = new Point(isoTile.x3d - displayX3d, isoTile.y3d - displayY3d);					
				if( isoTile.design.length > 0) {
					var cPointForChar : Point = cPoint.clone();
					if ( blockType == Block.TYPE_MUR || blockType == Block.TYPE_GHOST ) {
						displayCharacter(true, isoTile, cPointForChar, zone,blockType);
					}					
					for( var i:int = 0 ; i < isoTile.design.length ; i ++ ) {	
						if( isoTile.design[i] != -1 ) {										
							block =  mapModule.bitmapsRects[ isoTile.design[i] ] as Block;	
							if( block ) {																																
								var bd:BitmapData;	
								if( isoTile.isAuthorized ) {				
									bd = _mapModule.bitmaps[ block.bitmapNumber ] as BitmapData;
								} else {
									if( block.nonAuthorizedBitmap == null ) {	
										var colorValue:uint = -1;
										var alphaColor:uint = 0xff222222;
										bd = _mapModule.bitmaps[ block.bitmapNumber ] as BitmapData;
										block.nonAuthorizedBitmap = new BitmapData(bd.rect.width, bd.rect.height,true, 0x00000000);
										var blurry:BlurFilter = new BlurFilter(10,10);
							            var edge:BitmapFilter = convertiGrigio(); 
							            block.nonAuthorizedBitmap.applyFilter(bd,bd.rect,new Point(0,0),edge);
									}
									bd = block.nonAuthorizedBitmap;
								}						
								cPoint.y -=  block.rect.height - mapModule.tileSize;				
								if ( blockType == block.type) copyPixelsCliped(bd,  block.rect, cPoint,  zone);
							}	
						}				
					}					
					if ( blockType == Block.TYPE_MUR || blockType == Block.TYPE_GHOST ) displayCharacter(false, isoTile, cPointForChar, zone,blockType);					
				} else {
					if ( blockType == Block.TYPE_SOL) {
						block =  mapModule.bitmapsRects[ 0 ] as Block;												
						var bd:BitmapData = _mapModule.bitmaps[ block.bitmapNumber ] as BitmapData;							
						cPoint.y -=  block.rect.height - mapModule.tileSize;				
						if ( blockType == block.type) copyPixelsCliped(bd,  block.rect, cPoint,  zone);	
					}
				}
				
				
			}	
		}
		
		
		private function displayCharacter(before:Boolean, isoTile:IsoTile, _cPoint:Point, zone:int,blockType:int):void {
			
			if( isoTile.references.length > 0){
				var block:Block =  mapModule.bitmapsRects[ isoTile.design[0] ] as Block;												
				isoTile.triAllByDepth();
				for(var i:int = 0 ; i < isoTile.references.length ; i++ ) {
					var cPoint:Point = _cPoint.clone();
					cPoint.y -= block.rect.height - tileSize;
					var character:SimpleObject;
					var characterArr:Array;
					character = isoTile.references[i] as SimpleObject;
					characterArr = character.computeBitmapRectangleForDisplay(this,before, isoTile);
					if( character && characterArr) {
						var dec:Point = characterArr[0] as Point;						
						var characterRectangle:Rectangle = characterArr[1] as Rectangle;
						if ( characterRectangle ) {
							cPoint.x+=dec.x;
							cPoint.y = cPoint.y - (characterRectangle.height) + 32 + dec.y;	
							copyPixelsCliped((blockType == Block.TYPE_GHOST?character.bitmapDataGhost:character.bitmapData), characterRectangle, cPoint,  zone,(blockType == Block.TYPE_GHOST?false: true));
						}
					}
				}
			}
			
		}
		private function copyPixelsCliped( bd : BitmapData , rect:Rectangle , p:Point , zone:int = -1, isCharacter:Boolean = false):void {
			if( bd ) {
				p = p.clone();
				rect = rect.clone();
				var  doCopy:Boolean = true;			
				//up
				if( zone == 0 ) {				
					if( p.y >= tileSize ) doCopy = false;
					else if ( p.y + rect.height >= tileSize ) {
						if( rect.height > 31) {
							//trace("p="+p+", ret="+rect);
						}
						rect.height -= (p.y + rect.height - tileSize );
					}
					
				}else
				//down
				if( zone == 2 ) {
					if( p.y >= offScreen.height ) doCopy = false;
					else if ( p.y <=  (offScreen.height-tileSize) ) {
						var decy:int = (offScreen.height-tileSize) - p.y;
						p.y += decy;
						rect.y += decy;
						rect.height -= decy;
					}
					
				}else
				//right
				if( zone == 1 ) {
					if( p.x >= offScreen.width ) doCopy = false;
					else if ( p.x <=  (offScreen.width-tileSizeDouble) ) {
						var decx:int = (offScreen.width-tileSizeDouble) - p.x;
						p.x += decx;
						rect.x += decx;
						rect.width -= decx;
					}
					
				} else 
				//left
				if( zone == 3 ) {
					if( p.x >=  tileSizeDouble ) doCopy = false;
					else if ( p.x + rect.width >= tileSizeDouble ) {					
						rect.width -= p.x + rect.width-tileSizeDouble;
					}
					
				} else
				// zone for character movement
				if( zone == 4 ) {
					if( p.y  > zoneClipIsoTile.y + zoneClipIsoTile.height) {						
						 doCopy = false;
					} else  {
						if( p.x < zoneClipIsoTile.x ) {	
							var decx:int = 	zoneClipIsoTile.x - p.x;				
							p.x+=decx;
							rect.x += decx;
							rect.width -= decx;
						}
						if( p.y < zoneClipIsoTile.y ) {	
							var decy:int = zoneClipIsoTile.y - p.y;						
							p.y+=decy;
							rect.y += decy;
							rect.height -= decy;
						}
						if( p.x +rect.width> zoneClipIsoTile.x + zoneClipIsoTile.width) {	
							var decx:int = 	p.x +rect.width - (zoneClipIsoTile.x + zoneClipIsoTile.width);															
							rect.width -= decx;
						}
						if( p.y+rect.height > zoneClipIsoTile.y + zoneClipIsoTile.height) {
							var maxh:int = ( zoneClipIsoTile.y + zoneClipIsoTile.height ) - p.y ;
							rect.height = maxh;
						}
					}
					
				}
				if( doCopy) {
					offScreen.copyPixels( bd ,  rect , p );																
					if(isCharacter && !model.draggingMapIsOn) {
						var p2:Point = new Point(p.x - tileSize,p.y-tileSize);
						offScreenVisibility.copyPixels(bd ,rect , p);						
					}		
				}
			}
		}
		private function testObject(stageX:int, stageY:int, x3d:int, y3d:int, hit:IsoTile):IsoObjectMouseEvent {
			var evt:IsoObjectMouseEvent = null;
			if( hit != null ) {	
				
				var yy:int = hit.y2d;
				var xx:int = hit.x2d;
				
				for ( var i:int = 18 ; i >= 0; i-- ) {
					var xi:int = xx + i;
					var yi:int = yy + i;
					for ( var j:int = 0 ; j < 3; j++ ) {
						var dx:int = 0;
						var dy:int = 0;
						if( j == 1 ) dx = -1;
						if( j == 2 ) dy = -1;
						if( ! ( i== 0 && j!=0) ) {
						var tile:IsoTile = findIsoTile(xi+dx,yi+dy);
							if( tile!= null && tile.references.length > 0 ) {
								var so:SimpleObject = tile.references[tile.references.length-1] as SimpleObject;
								var characterArr:Array = so.computeBitmapRectangle( tile);
								if( characterArr != null ) {
									var dec:Point = characterArr[0] as Point;						
									var characterRectangle:Rectangle = characterArr[1] as Rectangle;
									var bitmap:BitmapData = so.bitmapData;
									
									var vx3d : int = x3d - (tile.x3d  - tileSize + dec.x) ;
									var vy3d : int = y3d - (tile.y3d  - (characterRectangle.height) + 32 + dec.y) ;
									
									if( vx3d > 0 ) {
										var hitColor :uint = bitmap.getPixel32(vx3d+characterRectangle.x,vy3d+characterRectangle.y);
										if( hitColor > 0 ) {																															
											evt = new IsoObjectMouseEvent("mouseOverObject",so, new Point(stageX, stageY));
											evt.localPoint3d = new Point(tile.x3d - displayX3d,tile.y3d - displayY3d);
											this.dispatchEvent(evt);
											return evt;																					
										}
									}				 
									
								}
							}
						}
					}
				}
			}
			return evt;	
		}
		
		
		
		public function testMousePositionHandler (event:MouseEvent):void {	
			//trace("IsoMap::testMousePositionHandler");		
			var found:Boolean = false;
			var stageX:Number = mouseX;
			var stageY:Number = mouseY;
			// calcul de la position exacte du pointeur de la souris
			var x3d:int = this.displayX3d + stageX  + visibleRect.x - tileSize;
			var y3d:int = this.displayY3d + stageY  + visibleRect.y ;
			var py2d:int = ( 2*y3d - x3d ) / 2 ;
			var px2d:int = x3d + py2d;
			var hit:IsoTile = testIsoTile (px2d, py2d);
			var evt:IsoObjectMouseEvent = testObject(stageX, stageY,x3d, y3d, hit);
			if( evt != null ) {			
				found = true;
			}	
			if( mouseOverObject && !found) {				
				var evt:IsoObjectMouseEvent = new IsoObjectMouseEvent("mouseOutObject",null, new Point(stageX, stageY));
				this.dispatchEvent(evt);
				mouseOverObject = false;
				currentIsoObjectMouseOver = null;
			}
			if( found ) {
				mouseOverObject = true;
				currentIsoObjectMouseOver = evt.isoObject;
				currentIsoObjectPoint3d = evt.localPoint3d;
			}
				
		}
		
		
		public function triByDepth(g1:SimpleObject, g2:SimpleObject):int {
         		if( g1._depth < g2._depth) return 1;
         		else return -1;
         	}
		private function processOperations():void {
			//trace("processOperations() [IN]");
			
			while(operations.length>0) {
				var op:String = operations.shift();
				//trace("operation="+op);
				var s:Array = op.split("_");
				//trace(s[0] +" nb args=" + (s.length -1));
				var action:String = s[0];
				if( action == IsoOperation.ADD_TO_DISPLAY_LIST ) {
					trace(s[1]);
					var io:IIsoObject = isoObjects[s[1]] as IIsoObject;
					io.visible = false;
					/* var cp:CircleParticle = new CircleParticle(0,0,30,false);
					io.particle = cp;
					cp.isoIbject = io;
					cp.addEventListener(CollisionEvent.COLLISION, collisionHandler);
					apeDefaultGroup.addParticle(cp);
					APEngine.step();
					APEngine.paint();*/
				} else if( action == IsoOperation.MOVE_ISO_OBJECT ) {	
					var so:SimpleObject = isoObjects[s[1]] as SimpleObject;
					so.removeFomMap();
					var px2d:Number = Number(s[2]);
					var py2d:Number = Number(s[3]);
					var xtile:Number = Math.floor(px2d/32);
					var ytile:Number = Math.floor(py2d/32);			
					for(var yy:int = 0 ; yy <= so.ey ; yy++ ) {
						for(var xx:int = 0 ; xx <= so.ex  ; xx++ ) {					
							var tile:IsoTile = findIsoTile( xtile+xx-1, ytile+yy-1 );
							if( tile ) {
								so.cases[yy][xx] = tile;	
								tile.addReference(so);	
							}			
						}
					}
					so.ox = px2d;
					so.oy = py2d;	
					var px3d = so.ox - so.oy;
					var py3d = Math.floor(( so.ox + so.oy )/2);
					so._depth = py3d;
					isoObjectsArray.sort(triByDepth);
					//isoObjectsArray.sortOn("_depth");
					so.visible = true;
				}else if( action == IsoOperation.PLACE_ISO_OBJECT ) {					
					var so:SimpleObject = isoObjects[s[1]] as SimpleObject;
					if( so.visible ) so.removeFomMap();
					else so.visible = true;
					var px2d:Number = Number(s[2]);
					var py2d:Number = Number(s[3]);
					var xtile:Number = Math.floor(px2d/32);
					var ytile:Number = Math.floor(py2d/32);			
					for(var yy:int = 0 ; yy <= so.ey ; yy++ ) {
						for(var xx:int = 0 ; xx <= so.ex  ; xx++ ) {					
							var tile:IsoTile = findIsoTile( xtile+xx-1, ytile+yy-1 );
							if( tile ) {
								so.cases[yy][xx] = tile;	
								tile.addReference(so);	
							}			
						}
					}
					so.ox = px2d;
					so.oy = py2d;	
					var px3d = so.ox - so.oy;
					var py3d = Math.floor(( so.ox + so.oy )/2);
					so._depth = py3d;
					//isoObjectsArray.sortOn("_depth");
					isoObjectsArray.sort(triByDepth);
					var opEvent:OperationEvent = new OperationEvent(IsoOperation.PLACE_ISO_OBJECT);
					opEvent.isoObject = so;
					dispatchEvent(opEvent);
				} else if( action == IsoOperation.REMOVE_ISO_OBJECT ) {					
					var so:SimpleObject = isoObjects[s[1]] as SimpleObject;
					so.removeFomMap();
					isoObjects[s[1]]=null;
					isoObjectsArray.splice(isoObjectsArray.indexOf(so),1);
				} else if( action == IsoOperation.ADD_NON_AUTHORIZED_ZONE ) {
					var x1:int = Number(s[1]);
					var y1:int = Number(s[2]);
					var x2:int = Number(s[3]);
					var y2:int = Number(s[4]);
					for( var yi:int = y1 ; yi <= y2 ; yi++ ) {
						for( var xi:int = x1 ; xi <= x2 ; xi++ ) {
							var tile:IsoTile = findIsoTile(xi,yi);
							tile.isAuthorized = false;
						}
					}
				} else if( action == IsoOperation.MOVE_ISOMAP ) {
					
						var destX2d:Number = Number(s[1]);
						var destY2d:Number = Number(s[2]);
						var destX3d:int = destX2d - destY2d;
						var destY3d:int = ( destX2d + destY2d )/2;
						// calcul de la position exacte du centre de l'ecran
						var actualX3d:int = this.displayX3d + this.width/2  + visibleRect.x - tileSize;
						var actualY3d:int = this.displayY3d + this.height/2  + visibleRect.y ;
						if( !(destX3d == actualX3d && destY3d == actualY3d) ) {
							regX = mouseX;
							regY = mouseY;
							var dx:int = - (destX3d - actualX3d);
							var dy:int = - (destY3d - actualY3d);
							regNewX = regX + dx;
							regNewY = regY + dy;
							newOperations.push(op);
						}else {
							var opEvent:OperationEvent = new OperationEvent(IsoOperation.MOVE_ISOMAP);						
							dispatchEvent(opEvent);
						}
					
				} else if( action == IsoOperation.ADD_SEGMENT_POINT ) {					
					var x2d:Number = Number(s[1]);
					var y2d:Number = Number(s[2]);
					_segments.push(new Point(x2d,y2d));
				} else if( action == IsoOperation.REMOVE_ALL_SEGMENTS ) {					
					_segments.splice(0,_segments.length);
				}
									
				
			}
		}
		public function moveIsoMap( destX1:Number, destY1:Number ): void {
			var s:String = IsoOperation.MOVE_ISOMAP + "_"+destX1+"_"+destY1;
			operations.push(s);
		}
		public function addIsoObject(so:IIsoObject, identifier:String, producer:Producer=null):void {
			so.identifier = identifier;
			isoObjects[so.identifier] = so;
			isoObjectsArray.push(so);
			var s:String = IsoOperation.ADD_TO_DISPLAY_LIST + "_"+so.identifier;
			if( producer ) {
				var message:AsyncMessage = new AsyncMessage();
				message.body = s;
				producer.send(message);
			}
			this.operations.push(s);
		}
		public function remove( so:IIsoObject, producer:Producer=null ): void {
			var s:String = IsoOperation.REMOVE_ISO_OBJECT + "_"+so.identifier;
			if( producer ) {
				var message:AsyncMessage = new AsyncMessage();
				message.body = s;
				producer.send(message);
			}
			this.operations.push(s);
		}
		public function place( so:IIsoObject, px2d:Number, py2d:Number, producer:Producer=null ): void {
			//trace(IsoOperation.PLACE_ISO_OBJECT + ": identifier="+so.identifier);
			var s:String = IsoOperation.PLACE_ISO_OBJECT + "_"+so.identifier+"_"+px2d+"_"+py2d;
			if( producer ) {
				var message:AsyncMessage = new AsyncMessage();
				message.body = s;
				producer.send(message);
			}
			this.operations.push(s);
		}
		public function moveIsoObject( so:IIsoObject, px2d:Number, py2d:Number, producer:Producer=null ): void {
			//trace(IsoOperation.PLACE_ISO_OBJECT + ": identifier="+so.identifier);
			var s:String = IsoOperation.MOVE_ISO_OBJECT + "_"+so.identifier+"_"+px2d+"_"+py2d;
			if( producer ) {
				var message:AsyncMessage = new AsyncMessage();
				message.body = s;
				producer.send(message);
			}
			this.operations.push(s);
		}
		public function addNonAuthorizedZone( x1:int, y1:int, x2:int, y2:int  ): void {
			var s:String = IsoOperation.ADD_NON_AUTHORIZED_ZONE + "_"+x1+"_"+y1+"_"+x2+"_"+y2;
			this.operations.push(s);
		}
		
		public function addSegmentPoint( x1:Number,y1:Number ): void {
			var s:String = IsoOperation.ADD_SEGMENT_POINT + "_"+x1+"_"+y1;			
			this.operations.push(s);
		}
		public function removeAllSegments(): void {
			var s:String = IsoOperation.REMOVE_ALL_SEGMENTS;
			this.operations.push(s);
		}
		public function scroll( ): void {
			//trace("IsoMap::scroll !isNaN(regX) && draggable regX/draggable=" + regX +"/" +draggable);
			if(!doRetrace && !isNaN(regX) && draggable) {	
				//trace("IsoMap::scroll");				
				var dx:int = regNewX-regX;
				var dy:int = regNewY-regY;
			
				if( dx > tileSizeDouble ) dx= tileSizeDouble;
				if( dx < -tileSizeDouble ) dx= -tileSizeDouble;
				if( dy > tileSize ) dy= tileSize;
				if( dy < -tileSize ) dy= -tileSize;
				visibleRect.x -= dx;
				visibleRect.y -= dy;
				if( visibleRect.x < 0 ) {
					visibleRect.x += tileSizeDouble;
					upleftXi--;
					upleftYi++;
					displayX3d-=tileSizeDouble;					
					retraceLeft(Block.TYPE_SOL);
					retraceSegments();
					//var rect:Rectangle = new Rectangle(0,0,tileSizeDouble,offScreen.height);					
					//offScreenVisibility.copyPixels(offScreen,rect, zeroPoint );
					retraceLeft(Block.TYPE_MUR);
					retraceLeft(Block.TYPE_GHOST);
				} else if( visibleRect.x > tileSizeDouble ) {
					visibleRect.x -= tileSizeDouble;
					upleftXi++;
					upleftYi--;
					displayX3d+=tileSizeDouble;					
					retraceRight(Block.TYPE_SOL);
					retraceSegments();
					//var rect:Rectangle = new Rectangle(offScreen.width - tileSizeDouble,0,tileSizeDouble,offScreen.height);					
					//offScreenVisibility.copyPixels(offScreen,rect, new Point(rect.x,0) );
					retraceRight(Block.TYPE_MUR);
					retraceRight(Block.TYPE_GHOST);
				}
				if( visibleRect.y < 0 ) {
					visibleRect.y += tileSize;
					upleftXi--;
					upleftYi--;
					displayY3d-=tileSize;					
					retraceUp(Block.TYPE_SOL);
					retraceSegments();
					retraceUp(Block.TYPE_MUR);
					retraceUp(Block.TYPE_GHOST);
				} else if( visibleRect.y > tileSize ) {
					visibleRect.y -= tileSize;
					upleftXi++;
					upleftYi++;
					displayY3d+=tileSize;					
					retraceDown(Block.TYPE_SOL);
					retraceSegments();
					retraceDown(Block.TYPE_MUR);
					retraceDown(Block.TYPE_GHOST);
				} else {
					retraceSegments();
				}
				regX = regNewX;
				regY = regNewY;	
				invalidateDisplayList();
				
				//trace("visibleRect="+visibleRect.x + ","+visibleRect.y);
			} 
			if( doRetrace ) {
				if(  model.draggingMapIsOn == false ) {
					offScreen.fillRect(offScreen.rect,0x000000);
					retrace(Block.TYPE_SOL);
					retraceSegments();
					//offScreenCharacters = new BitmapData(onScreen.width + _mapModule.tileSize*4 , onScreen.height +_mapModule.tileSize*2,true,0x00000000);				
					offScreenVisibility.copyPixels(offScreen,offScreen.rect, zeroPoint );								
					retrace(Block.TYPE_MUR);
					retrace(Block.TYPE_GHOST);
					invalidateDisplayList();
				}
			} else 
			if( doRetraceIsotile ) {
					retraceIsotile(Block.TYPE_SOL);
					offScreenVisibility.copyPixels(offScreen,zoneClipIsoTile, new Point(zoneClipIsoTile.x,zoneClipIsoTile.y) );								
					retraceIsotile(Block.TYPE_MUR);
					retraceIsotile(Block.TYPE_GHOST);
					invalidateDisplayList();
			}
		}
		override protected function commitProperties():void {
			super.commitProperties();
			processOperations();
			scroll();			
			
		}		
		
		 public function retraceSegments():void {
		 	if( _segments && _segments.length>0) {
			 	var first:Boolean = true;
			 	canevas.graphics.clear();
			 	canevas.graphics.lineStyle(2,0xFFFFFF,10,true);
			 	for each( var p:Point in _segments )
				{
					var x3d:Number = -this.displayX3d - visibleRect.x + 32 + p.x - p.y;
					var y3d:Number = -this.displayY3d - visibleRect.y + ( p.x + p.y )/2;
					
					trace("x3d,y3d="+x3d+","+y3d);
					if( first ) {
						canevas.graphics.moveTo(x3d,y3d);
						first = false;
					} else {
						canevas.graphics.lineTo(x3d,y3d);
					}								
				}
		 	}		 	
		 }
        public function getCurrentCharacter(_stageX:Number,_stageY:Number, _position:IsoMapMouseEvent=null):Array {
        	var ar:Array;
        	var s:SimpleObject = null;
        	if( _position == null ) {
        		_position = getCurrentMousePosition(_stageX,_stageY);
        	}
        	var x3d:int = this.displayX3d + _stageX  + visibleRect.x - tileSize;
			var y3d:int = this.displayY3d + _stageY  + visibleRect.y ;
			var found:Boolean = false;
        	for(var i:int=0 ; i < isoObjectsArray.length ;i++){
        		s = isoObjectsArray[i] as SimpleObject;
        		var hit:IsoTile = testIsoTile(s.ox,s.oy);
        		var b:Block =  mapModule.bitmapsRects[ hit.design[0] ] as Block;
        		
        		var px3d = s.ox - s.oy - tileSizeDouble;
				var py3d = Math.floor(( s.ox + s.oy )/2) - b.rect.height + tileSizeDouble - s.bitmapData.rect.height;
				trace("x3d,y3d="+x3d+","+y3d +" - " + px3d +","+py3d);
				var vx3d : int = x3d - px3d;
				var vy3d : int = y3d - py3d;
				if( vx3d > 0 ) {
					var hitColor :uint = s.bitmapData.getPixel32(vx3d,vy3d);
					if( hitColor > 0 ) {
						ar = new Array();
						ar.push(s);
						ar.push((s.bitmapData.width - vx3d - tileSizeDouble));
						ar.push((s.bitmapData.height - vy3d - tileSize));	
																																				
						trace("HIT");
						found = true;
						break;
					}
				}        			
        	}
        	
        	return ar;
        }
        public function getCurrentMousePosition(stageX:Number,stageY:Number):IsoMapMouseEvent {
			// calcul de la position exacte du pointeur de la souris
			var x3d:int = this.displayX3d + stageX  + visibleRect.x - tileSize;
			var y3d:int = this.displayY3d + stageY  + visibleRect.y ;
			var dMax:int = 256;
			
			
			var hit:IsoTile = null;
			var py2d:int = -1;
			var px2d:int = -1;
			while( hit == null && dMax>0 ) {
				dMax -= 32;
				py2d = ( 2*(y3d+dMax) - x3d ) / 2 ;
				px2d = x3d + py2d;
				hit = testIsoTile (px2d, py2d);
				
			}
			if(hit ) {
				var found:Boolean = false;
				var type:int = 0;	
				if( x3d - hit.x3d == 0 ) {
					type = 2;
				} else if( x3d - hit.x3d < 0 ) {
					type = 1;
				}
				
				while (!found ) {					
					var b:Block =  mapModule.bitmapsRects[ hit.design[0] ] as Block;
					if( b ) {
						var xx3d:int = x3d;
						var yy3d:int = y3d + b.rect.height - mapModule.tileSize;
						var pyy2d:int = ( 2*yy3d - xx3d ) / 2 ;
						var pxx2d:int = xx3d + pyy2d;
						var hitt:IsoTile = testIsoTile ( pxx2d, pyy2d );
						if( hitt && ( hit == hitt ) ) {
							found = true;	
							py2d = pyy2d;
							px2d = pxx2d;				
						} else {
							hit = null;
						}
					} 		 
					if( ! found ) {
						if(type == 0 || type == 2 ) py2d -= tileSize;
						if(type == 1 || type == 2 ) px2d -= tileSize;
						
						if( py2d >=0 && px2d >= 0 ) {
							hit = testIsoTile ( px2d, py2d );
						} else {
							hit = null;							
							found = true;
						}	
						if( type!=2) type = 1 - type;																	
					}
					
				}
			}
			
			/**var py2d:int = ( 2*y3d - x3d ) / 2 ;
			var px2d:int = x3d + py2d;
			var hit:IsoTile = testIsoTile (px2d, py2d);*/	
			return new IsoMapMouseEvent("tileClicked",hit, new Point(px2d,py2d))
        }
       
        
        public function collide(character:SimpleObject, p :Point):Boolean {  
        	var r:int = character.r;      	
        	var isoTileOrigin :IsoTile = testIsoTile(p.x, p.y);
        	if( isoTileOrigin ) {
        		if( isoTileOrigin.isAuthorized == false )return true;
        		var iB:int = isoTileOrigin.design[0];        		       		
        		if( iB == 0 ) return true;
        		var block:Block =  mapModule.bitmapsRects[ isoTileOrigin.design[0] ] as Block;
        		if( block!=null && block.type == Block.TYPE_MUR) return true;
        		var isoTile :IsoTile = null;
        		var d:Number ;        		
        		isoTile = mapModule.tilesTable[isoTileOrigin.y2d+1][isoTileOrigin.x2d-1] as IsoTile;
        		if( isoTile ) {
        			block =  mapModule.bitmapsRects[ isoTile.design[0] ] as Block;
        		} else {
        			block = new Block();
        			block.type = Block.TYPE_MUR;
        		}
        		if( (block!=null && block.type == Block.TYPE_MUR) || isoTile.isAuthorized == false) {
        			d = CollisionManager.distance(p.x,p.y, (isoTileOrigin.x2d-1)*32+31,(isoTileOrigin.y2d+1)*32);        			
        			if(  d <= r ) return true;
        		}
        		isoTile = testIsoTile(p.x - r , p.y);
        		//isoTile = mapModule.tilesTable[isoTileOrigin.y2d][isoTileOrigin.x2d-1] as IsoTile;
        		if( isoTile ) {
        			block =  mapModule.bitmapsRects[ isoTile.design[0] ] as Block;
        		} else {
        			block = new Block();
        			block.type = Block.TYPE_MUR;
        		}
        		if( (block!=null && block.type == Block.TYPE_MUR) || isoTile.isAuthorized == false) return true;
        		isoTile = mapModule.tilesTable[isoTileOrigin.y2d-1][isoTileOrigin.x2d-1] as IsoTile;
        		if( isoTile ) {
        			block =  mapModule.bitmapsRects[ isoTile.design[0] ] as Block;
        		} else {
        			block = new Block();
        			block.type = Block.TYPE_MUR;
        		}
        		if( (block!=null && block.type == Block.TYPE_MUR)|| isoTile.isAuthorized == false) {
        			d = CollisionManager.distance(p.x,p.y, (isoTileOrigin.x2d-1)*32+31,(isoTileOrigin.y2d-1)*32+31);        			
        			if(  d <= r ) return true;
        		}
        		isoTile = testIsoTile(p.x , p.y - r);
        		if ( isoTile ) {
        			block =  mapModule.bitmapsRects[ isoTile.design[0] ] as Block;
        		} else {
        			block = new Block();
        			block.type = Block.TYPE_MUR;
        		}
        		if( (block!=null && block.type == Block.TYPE_MUR) || isoTile.isAuthorized == false) return true;
        		
        		isoTile = mapModule.tilesTable[isoTileOrigin.y2d-1][isoTileOrigin.x2d+1] as IsoTile;        		
        		if( isoTile) {
        			block =  mapModule.bitmapsRects[ isoTile.design[0] ] as Block;
        		} else {
        			block = new Block();
        			block.type = Block.TYPE_MUR;
        		}
        		if( (block!=null && block.type == Block.TYPE_MUR) || isoTile.isAuthorized == false) {
        			d = CollisionManager.distance(p.x,p.y, (isoTileOrigin.x2d+1)*32,(isoTileOrigin.y2d-1)*32+31);        			
        			if(  d <= r ) return true;
        		}
        		isoTile = testIsoTile(p.x + r, p.y);
        		//isoTile = mapModule.tilesTable[isoTileOrigin.y2d][isoTileOrigin.x2d+1] as IsoTile;
        		if( isoTile ) {
        			block =  mapModule.bitmapsRects[ isoTile.design[0] ] as Block;
        		} else {
        			block = new Block();
        			block.type = Block.TYPE_MUR;
        		}
        		if( (block!=null && block.type == Block.TYPE_MUR)|| isoTile.isAuthorized == false) return true;
        		isoTile = mapModule.tilesTable[isoTileOrigin.y2d+1][isoTileOrigin.x2d+1] as IsoTile;
        		
        		if( isoTile ) {
        			block =  mapModule.bitmapsRects[ isoTile.design[0] ] as Block;
        		} else {
        			block = new Block();
        			block.type = Block.TYPE_MUR;
        		}
        		if( (block!=null && block.type == Block.TYPE_MUR)|| isoTile.isAuthorized == false) {
        			d = CollisionManager.distance(p.x,p.y, (isoTileOrigin.x2d+1)*32,(isoTileOrigin.y2d+1)*32);        			
        			if(  d <= r ) return true;
        		}
        		isoTile = testIsoTile(p.x , p.y + r);
        		//isoTile = mapModule.tilesTable[isoTileOrigin.y2d+1][isoTileOrigin.x2d] as IsoTile;
        		if( isoTile ) {
        			block =  mapModule.bitmapsRects[ isoTile.design[0] ] as Block;
        		} else {
        			block = new Block();
        			block.type = Block.TYPE_MUR;
        		}
        		if( (block!=null && block.type == Block.TYPE_MUR)|| isoTile.isAuthorized == false) return true;
        		
        		return false;
        	} else return true;
        	
        }
        
        public function testIsoTile (px2d:int, py2d:int):IsoTile {				
			
			var xtile:Number = Math.floor(px2d/mapModule.tileSize);
			var ytile:Number = Math.floor(py2d/mapModule.tileSize);			
			if( xtile >= 0 && xtile < mapModule.sizeX && ytile >= 0 && ytile < mapModule.sizeY ) {
				var tile:IsoTile = (mapModule.tilesTable[ytile][xtile] as IsoTile);				
				return tile;
			} else return null;			
        }
        public function findIsoTile (xtile:int, ytile:int):IsoTile {							
			if( xtile >= 0 && xtile < mapModule.sizeX && ytile >= 0 && ytile < mapModule.sizeY ) {
				var tile:IsoTile = (mapModule.tilesTable[ytile][xtile] as IsoTile);				
				return tile;
			} else return null;			
        }
        
       public function showDropFeedback(event:DragEvent):void {
       		DragManager.showFeedback(DragManager.NONE);
       }
       
       private function convertiGrigio():BitmapFilter
		{
			var r:Number=0.212671;
			var g:Number=0.715160;
			var b:Number=0.072169;
			return new ColorMatrixFilter
			(
				[r,g,b,0,0,
				r,g,b,0,0,
				r,g,b,0,0,
				0,0,0,1,0]   );
		}
	}
}